from pingparsing import PingParsing
from pingparsing import PingTransmitter
import time,json
from loggerconfig import logger
import os
import matplotlib.pyplot as plt
import numpy as np
# 设置中文字体为黑体
plt.rcParams['font.family']='SimHei'
# 解决负号显示为方块的问题
plt.rcParams['axes.unicode_minus'] = False


def do_ping():
    recv = []
    # 创建Ping发送对象，用于配置和发送ping请求
    transmitter = PingTransmitter()
    transmitter.destination = "fe80::ff:fe00:0"
    transmitter.count = 1
    transmitter.option_ipv6 = True # 启用 IPv6
    transmitter.interface = "8" # 接口名，%后面的数字

    # 创建Ping解析对象，用于解析ping结果
    ping_parsing = PingParsing()

    start_time = int(time.time())
    test_time = 10


    while int(time.time()) - start_time < test_time:
        result = transmitter.ping()
        
        parsed_result = ping_parsing.parse(result.stdout)
        logger.info("返回信息 {}".format(parsed_result.as_dict()))
        recv.append(parsed_result.as_dict())


        time.sleep(1)
    
    return recv

def analyze_pingdata():
    recv = do_ping()

    c_packet_transmit = 0   # 发送的数据包总数
    c_packet_receive = 0    # 接收的数据包总数
    c_packet_loss_count = 0 # 丢失的数据包总数
    packet_loss_rate = 0    # 丢包率
    rtt_list = []           # 往返时间列表
    rtt_min,rtt_avg,rtt_max = 0,0,0 # 往返最小时间、平均时间、最大时间


    for recv_data in recv:
        c_packet_transmit += dict(recv_data)["packet_transmit"]
        c_packet_receive += dict(recv_data)["packet_receive"]
        c_packet_loss_count += dict(recv_data)["packet_loss_count"]

        if type(dict(recv_data)["rtt_min"]) == float:
            rtt_list.append((recv_data)["rtt_min"])
    # 方差
    mean_transfer = sum(rtt_list) / len(rtt_list)
    variance_sum = 0
    for i in rtt_list:
        variance_sum += (i - mean_transfer) ** 2
    variance = variance_sum / len(rtt_list)
    # print("往返时间的方差为:", variance,"  往返时间的平均值:",mean_transfer)

    logger.info("--------测试结果--------")
    # logger.info("测试时长{}s".format(test_time))
    logger.info("发送的数据包总数{},接收的数据包总数{},丢失的数据包总数{},丢包率{}".format(c_packet_transmit,c_packet_receive,c_packet_loss_count,(c_packet_loss_count/c_packet_transmit)))
    logger.info("最小往返时间{},最大往返时间{},平均往返时间{},方差{}".format(min(rtt_list),max(rtt_list),(sum(rtt_list)/len(rtt_list)),variance))

    
    local_time_tuple = time.localtime()
    formatted_time = time.strftime("%Y-%m-%dT%H-%M-%S", local_time_tuple)

    logger.info("测试报告{}.txt".format(formatted_time))
    with open("./result/{}.txt".format(formatted_time),"w",encoding="UTF - 8") as f:
        # f.write("测试时长{}s\n".format(test_time))
        f.write("发送的数据包总数{},接收的数据包总数{},丢失的数据包总数{},丢包率{}\n".format(c_packet_transmit,c_packet_receive,c_packet_loss_count,(c_packet_loss_count/c_packet_transmit)))
        f.write("最小往返时间{},最大往返时间{},平均往返时间{}".format(min(rtt_list),max(rtt_list),(sum(rtt_list)/len(rtt_list))))

    # 画图
    x1 = np.array(range(len(rtt_list)))
    y1 = np.array(rtt_list)

    plt.plot(x1, y1, color='r', linestyle='--')

    # 设置x轴坐标显示，每隔5个显示一个刻度标签
    # 首先获取x轴数据的长度
    num_data_points = len(x1)
    # 生成要显示的刻度位置列表，从0开始，每隔5个取一个，直到数据长度范围内
    tick_positions = np.arange(0, num_data_points, 5)
    # 根据刻度位置获取对应的x轴坐标值
    tick_labels = x1[np.array(tick_positions)]
    plt.xticks(tick_positions, tick_labels)


    plt.xlabel('时间')
    plt.ylabel('往返时间 ms')
    plt.title('时间-往返时间图')
    save_path = './img/{}-time-rrt.jpg'.format(formatted_time)
    plt.savefig(save_path)
    plt.close()

def test_ping():
    # 创建Ping发送对象，用于配置和发送ping请求
    transmitter = PingTransmitter()
    transmitter.destination = "fe80::ff:fe00:0"
    transmitter.count = 1
    transmitter.option_ipv6 = True # 启用 IPv6
    transmitter.interface = "8" # 接口名，%后面的数字

    # 创建Ping解析对象，用于解析ping结果
    ping_parsing = PingParsing()

    start_time = int(time.time())
    test_time = 3600


    c_packet_transmit = 0   # 发送的数据包总数
    c_packet_receive = 0    # 接收的数据包总数
    c_packet_loss_count = 0 # 丢失的数据包总数
    packet_loss_rate = 0    # 丢包率
    rtt_list = []           # 往返时间列表
    rtt_min,rtt_avg,rtt_max = 0,0,0 # 往返最小时间、平均时间、最大时间



    while int(time.time()) - start_time < test_time:
        result = transmitter.ping()
        
        parsed_result = ping_parsing.parse(result.stdout)
        logger.info("返回信息 {}".format(parsed_result.as_dict()))

        c_packet_transmit += parsed_result.packet_transmit
        c_packet_receive += parsed_result.packet_receive
        c_packet_loss_count += parsed_result.packet_loss_count

        if type(parsed_result.rtt_min) == float:
            rtt_list.append(parsed_result.rtt_min)


        time.sleep(1)

    logger.info("--------测试结果--------")
    logger.info("测试时长{}s".format(test_time))
    logger.info("发送的数据包总数{},接收的数据包总数{},丢失的数据包总数{},丢包率{}".format(c_packet_transmit,c_packet_receive,c_packet_loss_count,(c_packet_loss_count/c_packet_transmit)))
    logger.info("最小往返时间{},最大往返时间{},平均往返时间{}".format(min(rtt_list),max(rtt_list),(sum(rtt_list)/len(rtt_list))))

    
    local_time_tuple = time.localtime()
    formatted_time = time.strftime("%Y-%m-%dT%H-%M-%S", local_time_tuple)

    logger.info("测试报告{}.txt".format(formatted_time))
    with open("./result/{}.txt".format(formatted_time),"w",encoding="UTF - 8") as f:
        f.write("测试时长{}s\n".format(test_time))
        f.write("发送的数据包总数{},接收的数据包总数{},丢失的数据包总数{},丢包率{}\n".format(c_packet_transmit,c_packet_receive,c_packet_loss_count,(c_packet_loss_count/c_packet_transmit)))
        f.write("最小往返时间{},最大往返时间{},平均往返时间{}".format(min(rtt_list),max(rtt_list),(sum(rtt_list)/len(rtt_list))))